<!-- 表单渲染 -->
<template>
  <div class="renderFormCont">
    <div v-if="BaseFormData && BaseFormData.formTitle" class="title">
      {{ BaseFormData.formTitle || '' }}
    </div>
    <div v-if="formData" class="formCont">
      <t-form
        ref="formValidatorStatus"
        :data="formData"
        :rules="rules"
        :label-width="100"
        width="100%"
        style="width: 100%; display: flex; flex-wrap: wrap"
        @reset="onReset"
        @submit="onSubmit"
      >
        <t-form-item
          v-for="item in renderFormData"
          v-show="
            !(
              item.data.isShow ||
              (!item.data.isShow && item.data.tripartiteType === 'hide')
            )
          "
          :key="item.id"
          :label-width="
            !item.data.isShowTitle
              ? item.data.isMust
                ? '10px'
                : 0
              : `${
                  item.data.title.length <= 6
                    ? 120
                    : item.data.title.length * 20
                } px`
          "
          :label="item.data.isShowTitle ? `${item.data.title}：` : ''"
          :name="`${item.id}`"
          :style="{ width: `${item.data.width ? item.data.width : 100}%` }"
        >
          <t-input
            v-if="item.type === 'input'"
            v-model="formData[`${item.id}`]"
            :placeholder="item.placeholder"
            :showLimitNumber="item.data.isStatistics"
            :defaultValue="item.defaultValue"
            :maxlength="Number(item.data.maxLength)"
            :minlength="Number(item.data.minLength)"
            :disabled="
              item.data.isReadOnly || item.data.tripartiteType === 'view'
            "
          ></t-input>
          <!-- 多行文本 -->
          <t-textarea
            v-if="item.type === 'textArea'"
            v-model="formData[`${item.id}`]"
            :placeholder="item.placeholder"
            :maxcharacter="Number(item.data.maxLength)"
            :showLimitNumber="item.data.isStatistics"
            :disabled="
              item.data.isReadOnly || item.data.tripartiteType === 'view'
            "
          />
          <!-- 单选 -->
          <t-radio-group
            v-if="item.type === 'radio'"
            v-model="formData[`${item.id}`]"
            :defaultValue="item.data.defaultValue"
            :style="{
              display: 'flex',
              'flex-direction': item.data.direction,
              'align-items': 'flex-start'
            }"
            :disabled="
              item.data.isReadOnly || item.data.tripartiteType === 'view'
            "
          >
            <t-radio
              v-for="it in item.data.titlab"
              :key="it"
              :label="it"
              :value="it"
            />
          </t-radio-group>
          <!-- 多选 -->
          <t-checkbox-group
            v-if="item.type === 'checkbox'"
            :value="formData[`${item.id}`] || []"
            :defaultValue="item.data.defaultValue || []"
            :style="{ display: 'flex', 'flex-direction': item.data.direction }"
            :max="Number(item.data.maxLength) || Infinity"
            :disabled="
              item.data.isReadOnly || item.data.tripartiteType === 'view'
            "
            @change="checkboxHandle"
            @click="checkboxClick(item)"
          >
            <t-checkbox
              v-for="(it, ind) in item.data.titlab"
              :key="ind"
              :label="it"
              :value="it"
            />
          </t-checkbox-group>
          <!-- 下拉框 -->
          <t-select
            v-if="item.type === 'select'"
            :value="formData[`${item.id}`]"
            placeholder="请选择"
            :multiple="item.data.maxLength > 1"
            :max="Number(item.data.maxLength) || 100"
            size="small"
            class="selectCont"
            :disabled="
              item.data.isReadOnly || item.data.tripartiteType === 'view'
            "
            @click="selectClick(item)"
            @change="defaultValueHandel"
          >
            <t-option
              v-for="it in item.data.titlab"
              :key="it"
              :label="it"
              :value="it"
            />
          </t-select>
          <!-- 开关 -->
          <t-switch
            v-if="item.type === 'switch'"
            v-model="formData[`${item.id}`]"
            :disabled="
              item.data.isReadOnly || item.data.tripartiteType === 'view'
            "
          />
          <!-- 评分 -->
          <t-rate
            v-if="item.type === 'rate'"
            v-model="formData[`${item.id}`]"
            :disabled="
              item.data.isReadOnly || item.data.tripartiteType === 'view'
            "
            allowHalf
            size="20px"
          ></t-rate>
          <!-- 滑块 -->
          <t-slider
            v-if="item.type === 'slider'"
            v-model="formData[`${item.id}`]"
            :max="item.data.maxValue"
            :min="item.data.minValue"
            :step="item.data.step"
            :disabled="
              item.data.isReadOnly || item.data.tripartiteType === 'view'
            "
            size="small"
          />
          <!-- 日期选择器 -->
          <t-date-picker
            v-if="item.type === 'timeSelect'"
            v-model="formData[`${item.id}`]"
            :mode="
              item.data.dateType && item.data.dateType !== 'dateTime'
                ? item.data.dateType
                : 'date'
            "
            :disabled="
              item.data.isReadOnly || item.data.tripartiteType === 'view'
            "
            :disableDate="disableDateHandle(item)"
            clearable
            :enable-time-picker="item.data.dateType === 'dateTime'"
          />
          <!-- 日期区间 -->
          <t-date-range-picker
            v-if="item.type === 'dateArea'"
            v-model="formData[`${item.id}`]"
            clearable
            size="small"
            :mode="
              item.data.dateType && item.data.dateType !== 'dateTime'
                ? item.data.dateType
                : 'date'
            "
            :disabled="
              item.data.isReadOnly || item.data.tripartiteType === 'view'
            "
            :disableDate="dateAreadisableDateHandle(item)"
            :enable-time-picker="item.data.dateType === 'dateTime'"
          />
          <!-- 数字输入框 -->
          <t-input-number
            v-if="item.type === 'number'"
            v-model="formData[`${item.id}`]"
            :max="item.data.maxValue || Infinity"
            :min="item.data.minValue || -Infinity"
            :disabled="
              item.data.isReadOnly || item.data.tripartiteType === 'view'
            "
            placeholder="请输入默认值"
          >
            <template #label
              ><span>{{ item.data.prefix }}</span></template
            >
          </t-input-number>
          <!-- 附件 -->
          <t-upload
            v-if="item.type === 'file'"
            :action="fileUpUrl"
            size="small"
            :size-limit="{ size: item.data.fileSize || 1024 * 10, unit: 'KB' }"
            :max="item.data.maxFileNum || 99"
            :disabled="
              item.data.isReadOnly || item.data.tripartiteType === 'view'
            "
            @success="uploadSuccess"
          />
          <!-- 图片 -->
          <t-upload
            v-if="item.type === 'img'"
            :action="fileUpUrl"
            size="small"
            theme="image"
            :size-limit="{ size: item.data.fileSize || 1024 * 10, unit: 'KB' }"
            :max="item.data.maxFileNum || 99"
            :disabled="
              item.data.isReadOnly || item.data.tripartiteType === 'view'
            "
            @success="uploadSuccess"
          />
          <!-- 位置 -->
          <div v-if="item.type === 'position'" class="position">
            <Amap :data="item" @valueChange="mapAddValue"></Amap>
          </div>
          <!---子表单-->
          <!-- TODO 子表这块效验先放一放 目前的效验是写到form里的 效验字段是id 但子表id 是重复无法作为效验的key-->
          <div
            v-if="item.type === 'subform' && item.data.formData.length != 0"
            class="subformItem"
          >
            <div
              v-for="(it, i) in subList"
              :key="it"
              :class="{ item: true, fx: item.data.formData.length <= 5 }"
            >
              <span v-if="i === 0" class="add" @click="subformAct()">+</span>
              <span v-else class="red" @click="subformAct(i)">-</span>
              <subRenderForm
                :id="item.id"
                :dataKey="it"
                :fromDataes="item.data.formData"
                :initData="formData[`${item.id}`]"
                @valueChange="subfromValue"
              />
            </div>
          </div>
          <!-- 省市区 -->
          <t-cascader
            v-if="item.type === 'location' && item.data.level === '1'"
            v-model="formData[`${item.id}`]"
            :options="cityList"
          />
          <t-cascader
            v-if="item.type === 'location' && item.data.level === '2'"
            v-model="formData[`${item.id}`]"
            :options="addressList"
          />
          <!-- 分割线 -->
          <div
            v-if="item.type === 'line'"
            :style="{
              position: `relative`,
              margin: '10px 0 3px 0',
              borderTop: `${item.data.type} ${item.data.height}px ${item.data.color}`
            }"
          >
            <span
              v-if="
                item.data.placeholder !== '' &&
                item.data.placeholder !== '请输入内容'
              "
              style="
                position: absolute;
                left: 50%;
                padding: 0 10px;
                line-height: 22px;
                transform: translate(-50%);
                background: #fff;
              "
              :style="{ top: `-${11 + item.data.height / 2}px` }"
              >{{ item.data.placeholder }}</span
            >
          </div>
          <!-- 按钮 -->
          <div
            v-if="item.type === 'button'"
            :style="{ display: 'flex', justifyContent: item.data.align }"
          >
            <t-button size="small" @click="buttonHandle(item)">{{
              item.data.name
            }}</t-button>
          </div>
          <!-- 部门 -->
          <!-- <t-select-input
            v-if="item.data.isSearch"
            :value="item.data.formName"
            :popup-visible="popupVisible"
            :popup-props="{ overlayInnerStyle: { padding: '6px' } }"
            placeholder="请选择"
            clearable
            allow-input
            size="small"
            @popup-visible-change="onPopupVisibleChange"
            @clear="onClear"
            @input-change="initOptions"
          >
            <template #panel>
              <ul
                v-if="departmentOptions.length > 0"
                class="tdesign-demo__select-input-ul-single"
              >
                <li
                  v-for="item in departmentOptions"
                  :key="item.id"
                  @click="() => onOptionClick(item)"
                >
                  {{ item.name }}
                </li>
              </ul>
              <ul v-else>
                <li class="t-select__empty">暂无数据</li>
              </ul>
            </template>
            <template #suffixIcon>
              <icon name="chevron-down" size="large" />
            </template>
          </t-select-input>-->
          <div
            v-if="item.type === 'department'"
            :style="{ display: 'flex', justifyContent: item.data.align }"
          >
            <t-select v-model="item.data.defaultValue" placeholder="请选择">
              <t-option
                v-for="it in departmentOptions"
                :key="it"
                :label="it"
                :value="it"
              />
            </t-select>
          </div>
          <!-- 人员 -->
          <div
            v-if="item.type === 'member'"
            :style="{ display: 'flex', justifyContent: item.data.align }"
          >
            <t-select v-model="item.data.defaultValue" placeholder="请选择">
              <t-option
                v-for="it in departmentOptions"
                :key="it"
                :label="it"
                :value="it"
              />
            </t-select>
          </div>
        </t-form-item>
      </t-form>
    </div>
    <!-- <div v-eles>
      表单生成中...
    </div> -->
    <div v-if="openType === 'preview'" class="fx" style="margin-top: 20px">
      <div class="bt" style="margin: 20px; width: 100px" @click="onSubmit">
        数据提交
      </div>
      <div class="bt" style="margin: 20px; width: 100px" @click="cacheHandle">
        数据暂存
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, getCurrentInstance, onMounted, computed } from 'vue'
import { MessagePlugin } from 'tdesign-vue-next'
import subRenderForm from './components/renderFromCom/SubRenderForm.vue'
import Amap from './components/renderFromCom/Amap.vue'
import { useFormData } from '@/store'
import { formDataes } from '@/api/form'
import addressList from './components/attrComponents/addressList'

const store = useFormData()

const departmentOptions = ref([])

// 禁用日期 - 日期选择
const disableDateHandle = (item) => {
  const data = {
    before: item.data.minValue,
    after: item.data.maxValue
  }
  for (const key in data) {
    if (!data[key]) {
      data[key] = undefined
    }
  }
  return JSON.parse(JSON.stringify(data))
}
// 禁用日期 - 日期区间 - 时间区间如果是周的话 需要把禁用的日期处理一下
const dateAreadisableDateHandle = (item) => {
  const data = {
    before:
      item.data.dateType === 'week'
        ? item.data.disableDaySt
        : item.data.minValue,
    after:
      item.data.dateType === 'week'
        ? item.data.disableDayLt
        : item.data.maxValue
  }
  for (const key in data) {
    if (!data[key]) {
      data[key] = undefined
    }
  }
  return JSON.parse(JSON.stringify(data))
}
// 动态渲染表单的 数据 - 来源于设计表单的数据
const BaseFormData = ref()
const renderFormData = ref()
const formValidatorStatus = ref()
const openType = ref('preview') // 'render' 表单正常使用模式,  'preview' 预览模式 不走接口
const formId = ref('') // 表单ID
const dataId = ref('') // 表单的初始数据ID - 编辑用的
const configBaseData = ref() // 传入的数据
// 获取APP根实例
const instance = getCurrentInstance()
const props = defineProps({
  preview: String
})

const fileUpUrl = ref('')
// 初始化渲染表单
onMounted(() => {
  if (props.preview) {
    openType.value = 'preview'
  }
  // 被输入接入系统的
  const instances: any = instance.appContext.app
  console.log('配置参数::', instances.$initConfig)
  if (instances.$initConfig) {
    const { type, baseData, uploadConf } = instances.$initConfig
    formId.value = baseData.formId
    dataId.value = baseData.dataId
    fileUpUrl.value = uploadConf.url
    configBaseData.value = baseData
    if (props.preview) {
      openType.value = 'preview'
    } else if (type) {
      openType.value = type
    }
  }
  initDataHandle()
})
// 按钮
const buttonHandle = (item) => {
  if (item.data.type === 'url') {
    document.location.href = item.data.value
  } else {
    document.location.href = `tel:${item.data.value}`
  }
}
// 图片上传成功
const uploadSuccess = (val) => {
  console.log('图片上传成功', val)
  // attributeset.data.defaultValue = val.response.url
}
// 初始化的表单数据
const initDataHandle = () => {
  if (openType.value === 'preview') {
    // 使用 pinia 的缓存数据 这个后面做预览使用
    const storeData = (store.getSubmitFormData as any).palyload
    if (
      storeData &&
      Object.keys(storeData.formDetail.formData[0].data).length > 0
    ) {
      BaseFormData.value = storeData.formDetail.baseFormData // data.baseFormData
      renderFormData.value = storeData.formDetail.formData[0].data //
      formDataInit()
    }
  } else {
    // 初始化数据 - 使用接口数据 - 表单结构初始化
    getFromDataDetails()
    // 表单数据初始化 - 数据获取
    getFromDataes()
  }
}

// 下拉的处理 -- start
// 暂存下拉点击选项
const selectItem = ref()
const selectClick = (item) => {
  selectItem.value = item
}
// 选择默认值  这里有两种模式 一种 正常单选下拉 一种多选标签式的
const defaultValueHandel = (val, context) => {
  if (!val) return
  // 多选
  if (
    selectItem.value.data.maxLength !== undefined &&
    Number(selectItem.value.data.maxLength) > 1 &&
    context.trigger === 'check'
  ) {
    selectHandle(val, { current: context.option.value })
  } else {
    formData.value[`${selectItem.value.id}`] = val
  }
}
// 互斥选项处理 - 多选
const selectHandle = (val, context) => {
  const item = selectItem.value
  // 选中
  if (item.data.excludeOptions && item.data.excludeOptions.length > 0) {
    const ind = item.data.excludeOptions.indexOf(context.current)
    // 如果有互斥项已经被选 做标记
    const valInd = formData.value[`${item.id}`].indexOf(context.current)
    // 已经选择了一个互斥项
    if (
      Array.isArray(formData.value[`${item.id}`]) &&
      formData.value[`${item.id}`].length === 1 &&
      item.data.excludeOptions.indexOf(formData.value[`${item.id}`][0]) !== -1
    ) {
      formData.value[`${item.id}`] = [context.current]
      return
    }
    // 互斥项处理 - 互斥选项中没有并且也没有被选中过
    if (ind === -1 && valInd === -1) {
      if (
        Array.isArray(formData.value[`${item.id}`]) &&
        formData.value[`${item.id}`].length === 0
      ) {
        formData.value[`${item.id}`] = [context.current]
      } else {
        formData.value[`${item.id}`].push(context.current)
      }
      // 在互斥选项中有并且已经被选中直接清空
    } else if (ind !== -1 && valInd !== -1) {
      formData.value[`${item.id}`] = []
      // 在互斥选项中有并且没有被选中 直接选中
    } else if (ind !== -1 && valInd === -1) {
      formData.value[`${item.id}`] = [context.current]
    }
  } else {
    formData.value[`${item.id}`] = val
  }
}
// 下拉的处理 -- end

// 获取表单控件的详情
const getFromDataDetails = async () => {
  const id = formId.value
  const params = {
    id: 'GET_MY_FORM',
    messageAuth: {
      tenant: 'tenant_hiss',
      currentUser: {
        userId: '1',
        userName: '张三',
        userGroups: ''
      }
    },
    palyload: {
      ids: id,
      query: ''
    }
  }
  await formDataes(params).then((res) => {
    const resData = res.data.res
    const context = JSON.parse(resData[0].context)
    BaseFormData.value = context.baseFormData
    const data = context.formData[0].data
    // 和三方（流程）的配置信息进行融合  edit：可编辑 view：不可编辑 hide：不显示
    if (Object.keys(configBaseData.value).length > 0) {
      const { fields } = configBaseData.value.formConfig
      for (const key in data) {
        for (const it in fields) {
          if (String(data[key].id) === String(fields[it].fieldName)) {
            data[key].data.tripartiteType = fields[it].type
          }
        }
      }
    }
    renderFormData.value = data
  })
}

// 表单数据
const formData = ref({})
// 暂存多选点击选项
const changeItem = ref()
const checkboxClick = (item) => {
  changeItem.value = item
}
// 互斥选项处理 - 多选
const checkboxHandle = (val, context) => {
  const item = changeItem.value
  if (!Array.isArray(formData.value[`${item.id}`])) {
    formData.value[`${item.id}`] = []
  }
  const itData = formData.value[`${item.id}`]
  // 取消选项
  const ckInd = Array.isArray(itData) ? itData.indexOf(context.current) : -1
  if (ckInd !== -1) {
    formData.value[`${item.id}`].splice(ckInd, 1)
    return
  }
  // 选中
  if (item.data.excludeOptions && item.data.excludeOptions.length > 0) {
    const ind = item.data.excludeOptions.indexOf(context.current)
    // 如果有互斥项已经被选 做标记
    const valInd = itData.indexOf(context.current)
    // 已经选择了一个互斥项
    if (
      Array.isArray(itData) &&
      itData.length === 1 &&
      item.data.excludeOptions.indexOf(itData[0]) !== -1
    ) {
      formData.value[`${item.id}`] = [context.current]
      return
    }
    // 互斥项处理 - 互斥选项中没有并且也没有被选中过
    if (ind === -1 && valInd === -1) {
      if (Array.isArray(itData) && itData.length === 0) {
        formData.value[`${item.id}`] = [context.current]
      } else {
        formData.value[`${item.id}`].push(context.current)
      }
      // 在互斥选项中有并且已经被选中直接清空
    } else if (ind !== -1 && valInd !== -1) {
      formData.value[`${item.id}`] = []
      // 在互斥选项中有并且没有被选中 直接选中
    } else if (ind !== -1 && valInd === -1) {
      formData.value[`${item.id}`] = [context.current]
    }
  } else {
    formData.value[`${item.id}`] = val
  }
}
// input 效验
// 表单效验 - 动态生成的
const rules = computed(() => {
  const rulesData = {}
  if (renderFormData.value && Object.keys(renderFormData.value).length !== 0) {
    renderFormData.value.forEach((item) => {
      // 必填效验
      if (item.data.isMust) {
        rulesData[`${item.id}`] = [
          {
            required: true,
            message: item.data.placeholder,
            type: 'error',
            trigger: 'blur'
          }
        ]
      }
      // 如果input并且做了特殊效验 - 身份证、游戏、数字等  长度效验也是针对input的
      if (item.type === 'input') {
        const validatorFn =
          item.data.inputType !== 'none' ? rulesSet(item.data.inputType) : null
        const rulesList = {
          validator: validatorFn,
          message: item.data.errorPrompt || '请输入正确的值'
        }
        if (validatorFn && rulesData[`${item.id}`] !== undefined) {
          rulesData[`${item.id}`].push(rulesList)
        } else if (validatorFn && rulesData[`${item.id}`] === undefined) {
          rulesData[`${item.id}`] = [rulesList]
        }

        // 长度效验 有写组件自带最小值、最大值的效验 但有些没有 这里不做区分 只要有最大或者最小值全部进行效验
        if (item.data.minLength && rulesData[`${item.id}`] !== undefined) {
          rulesData[`${item.id}`].push({
            min: Number(item.data.minLength),
            message: '请输入正确的长度'
          })
        } else if (
          item.data.minLength &&
          rulesData[`${item.id}`] === undefined
        ) {
          rulesData[`${item.id}`] = [
            { min: Number(item.data.minLength), message: '请输入正确的长度' }
          ]
        }
        // 最大长度
        if (item.data.maxLength && rulesData[`${item.id}`] !== undefined) {
          rulesData[`${item.id}`].push({
            max: Number(item.data.maxLength),
            message: '请输入正确的长度'
          })
        } else if (
          item.data.maxLength &&
          rulesData[`${item.id}`] === undefined
        ) {
          rulesData[`${item.id}`] = [
            { max: Number(item.data.maxLength), message: '请输入正确的长度' }
          ]
        }
      }
      // 对选项的数量单独做个效果规则
      if (
        item.type === 'checkbox' ||
        (item.type === 'select' &&
          item.data.maxLength &&
          item.data.maxLength > 1)
      ) {
        // 最小长度效验
        if (item.data.minLength && rulesData[`${item.id}`] !== undefined) {
          rulesData[`${item.id}`].push({
            validator: (value) => {
              return value.length >= item.data.minLength
            },
            message: `请输入正确的选项, 最少应选${item.data.minLength}个`
          })
        } else if (
          item.data.minLength &&
          rulesData[`${item.id}`] === undefined
        ) {
          rulesData[`${item.id}`] = [
            {
              validator: (value) => {
                return value.length >= item.data.minLength
              },
              message: `请输入正确的选项, 最少应选${item.data.minLength}个`
            }
          ]
        }
        // 最大长度效验
        if (item.data.maxLength && rulesData[`${item.id}`] !== undefined) {
          rulesData[`${item.id}`].push({
            validator: (value) => {
              console.log(value, value.length)
              return value.length <= item.data.maxLength
            },
            message: `请输入正确的选项, 最多应选${item.data.maxLength}个`
          })
        } else if (
          item.data.maxLength &&
          rulesData[`${item.id}`] === undefined
        ) {
          rulesData[`${item.id}`] = [
            {
              validator: (value) => {
                console.log(value, value.length)
                return value.length <= item.data.maxLength
              },
              message: `请输入正确的选项, 最多应选${item.data.maxLength}个`
            }
          ]
        }
      }
      // 如果是数字输入的话 处理一下小数位的效验
      if (
        item.type === 'number' &&
        item.data.floatNum &&
        rulesData[`${item.id}`] !== undefined
      ) {
        rulesData[`${item.id}`].push({
          validator: (value) => {
            return String(value).split('.').length >= 2
              ? String(value).split('.')[1].length <= item.data.floatNum
              : true
          },
          message: '请输入正确的长度'
        })
      }
      if (
        item.type === 'number' &&
        item.data.floatNum &&
        rulesData[`${item.id}`] === undefined
      ) {
        rulesData[`${item.id}`] = [
          {
            validator: (value) => {
              return String(value).split('.').length >= 2
                ? String(value).split('.')[1].length <= item.data.floatNum
                : true
            },
            message: '请输入正确的长度'
          }
        ]
      }
    })
  }
  console.log('效验规则：', rulesData)
  return rulesData
})

// 数字效验 包含 正数 负数 小数
const numberRule = /^-?\d+(\.\d+)?$/
// 整数类型 包含正、负整数和0
const intRule = /^-?\d+$/
// 浮点数类型 不包含正、负整数类型和0
const floatRule = /^-?(?!0)\d+(\.\d+)?$/
// url
const urlRule =
  /^(?:https?:\/\/)?(?:www\.)?[a-zA-Z0-9-]+\.[a-zA-Z]{2,}(?:\/[\w-]*)*\/?$/
// emil 邮箱
const emilRule = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/
// 手机号效验
const phoneRule = /^1[3|4|5|6|7|8|9]\\d{9}$/
// 身份证
const idNumberRule18 =
  /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
const idNumberRule15 =
  /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/

// input的特殊效验规则
const rulesSet = (tg) => {
  let ruleResult: Function = null
  switch (tg) {
    case 'number':
      ruleResult = (value) => numberRule.test(value)
      break
    case 'int':
      ruleResult = (value) => intRule.test(value)
      break
    case 'float':
      ruleResult = (value) => floatRule.test(value)
      break
    case 'url':
      ruleResult = (value) => urlRule.test(value)
      break
    case 'emil':
      ruleResult = (value) => emilRule.test(value)
      break
    case 'phone':
      ruleResult = (value) => phoneRule.test(value)
      break
    case 'idNumber':
      ruleResult = (value) =>
        idNumberRule18.test(value) || idNumberRule15.test(value)
      break
  }
  return ruleResult
}
// 点位 地图
const mapAddValue = (val) => {
  formData.value[`${val.item.id}`] = val.data
}

// 默认值处理 - 如果是checkbox 需要提前处理checkbox
const formDataInit = (value?: Object) => {
  let baseFormData = {}
  if (renderFormData.value) {
    renderFormData.value.forEach((item) => {
      if (item.type === 'checkbox' || item.type === 'dateArea') {
        baseFormData[`${item.id}`] = []
      }
      if (
        item.data.defaultValue !== '' &&
        item.data.defaultValue !== undefined
      ) {
        baseFormData[`${item.id}`] = item.data.defaultValue
      }
    })
  }
  if (value) {
    baseFormData = { ...baseFormData, ...value }
  }
  formData.value = baseFormData
}
// 数据暂存提交
const cacheHandle = async () => {
  const dom = formValidatorStatus.value
  if (dom.validate()) {
    const params = {
      id: 'SUBMIT_FORM_DATA',
      messageAuth: {
        tenant: 'tenant_hiss',
        currentUser: {
          userId: '1',
          userName: '张三',
          userGroups: ''
        }
      },
      palyload: {
        modelId: configBaseData.value.modelId, // 流程 ID 'dc0af849c7f98019a6918debe03fcf56'
        formId: configBaseData.value.formId, // 表单ID
        dataId: configBaseData.value.dataId || dataId.value, // 数据ID
        draft: true, // 数据缓存
        formConfig: configBaseData.value.formConfig,
        formData: [{ page: 1, data: { ...formData.value } }]
      }
    }
    const data = await formDataes(params)
    dataId.value = data.data.result
    return data
  }
}
// 表单数据提交
const onSubmit = async () => {
  const dom = formValidatorStatus.value
  if (dom.validate()) {
    const params = {
      id: 'SUBMIT_FORM_DATA',
      messageAuth: {
        tenant: 'tenant_hiss',
        currentUser: {
          userId: '1',
          userName: '张三',
          userGroups: ''
        }
      },
      palyload: {
        modelId: configBaseData.value.modelId, // 流程 ID 'dc0af849c7f98019a6918debe03fcf56'
        formId: configBaseData.value.formId, // 表单ID
        dataId: configBaseData.value.dataId || dataId.value, // 数据ID
        formConfig: configBaseData.value.formConfig,
        draft: false,
        formData: [{ page: 1, data: { ...formData.value } }]
      }
    }

    const data = await formDataes(params)
    dataId.value = data.data.result
    return data
  }
}

// 获取表单数据-表单的初始数据
const getFromDataes = () => {
  const dom = formValidatorStatus.value
  if (dom.validate()) {
    const params = {
      id: 'GET_MY_FORM_DATA',
      messageAuth: {
        tenant: 'tenant_hiss',
        currentUser: {
          userId: '1',
          userName: '张三',
          userGroups: ''
        }
      },
      palyload: {
        modelId: configBaseData.value.modelId, // 流程 ID 'dc0af849c7f98019a6918debe03fcf56'
        formId: configBaseData.value.formId, // 表单ID
        dataId: configBaseData.value.dataId || dataId.value // 数据ID
      }
    }
    if (!params.palyload.dataId) {
      return
    }
    formDataes(params).then((res) => {
      // 默认值的处理
      if (
        res.code === 200 &&
        res.data.result &&
        Object.keys(res.data.result).length > 0
      ) {
        formDataInit(res.data.result)
      } else {
        formDataInit()
      }
    })
  }
}
// 省市区模块展示 城市数据处理 三级数据改为二级
const cityList = addressList.map((obj) => {
  const newCity = { ...obj }
  newCity.children = newCity.children.map((n) => {
    const ctList = { ...n }
    ctList.children = []
    return ctList
  })
  return newCity
})

// 子表
const subList = ref([0])
const subformAct = (num?: number) => {
  if (num) {
    subList.value.splice(num, 1)
  } else {
    subList.value.push(subList.value.at(-1) + 1)
  }
}
const subformData = ref([])
// 接收子表参数
const subfromValue = (val) => {
  if (subformData.value.length === 0) {
    subformData.value.push(val)
  } else {
    const ind = subformData.value.findIndex((n) => {
      return n.datakey === val.datakey
    })
    if (ind === -1) {
      subformData.value.push(val)
    } else {
      subformData.value.splice(ind, 1, val)
    }
  }
  formData.value[`${val.id}`] = formatData(subformData.value)
}

const formatData = (val) => {
  let data = []
  if (val && Array.isArray(val)) {
    data = val.map((n) => n.data)
  }
  return data
}
// 提交挂载到根实例上
const baseApp: any = instance.appContext.app
baseApp.submitFn = onSubmit
baseApp.submitCatchFn = cacheHandle

// 表单重置
const onReset = () => {
  MessagePlugin.success('重置成功')
}
</script>
<style lang="less" scoped>
.renderFormCont {
  .t-form {
    width: 100%;
  }

  width: 80%;
  margin: 0 auto;
  // padding: 30px;
  border-radius: 4px;
  background-color: #fff;
  min-height: calc(100vh - 200px);

  .title {
    font-size: 22px;
    line-height: 50px;
    text-align: center;
    margin-bottom: 30px;
  }

  .formCont {
    display: flex;
    flex-wrap: wrap;
  }
  .position {
    width: 100%;
  }
}
</style>
<style lang="less">
.subformItem {
  border: solid 1px #ccc;
  padding: 10px;
  margin-bottom: 10px;
  margin-top: 10px;
  .item {
    border-bottom: solid 1px #e8e8e8;

    &:last-child {
      border: none;
    }
  }

  .add,
  .red {
    color: blue;
    position: relative;
    top: 22px;
    cursor: pointer;
    font-size: 22px;
    font-weight: bold;
  }
  .red {
    color: red;
  }
  .position {
    width: 100%;
  }
}
</style>
